package com.useeinfo.oa.modules.security.biz;

import com.alibaba.fastjson.JSONObject;
import com.useeinfo.framework.extend.biz.CrudBiz;
import com.useeinfo.framework.sugar.data.QueryParam;
import com.useeinfo.framework.sugar.tools.CommonSugar;
import com.useeinfo.framework.sugar.tools.StringConverters;
import com.useeinfo.oa.common.utils.ResultUtil.ResultDto;
import com.useeinfo.oa.common.utils.ResultUtil.ResultUtil;
import com.useeinfo.oa.modules.security.dao.SystemAuthorityDao;
import com.useeinfo.oa.modules.security.entity.SystemAuthority;
import com.useeinfo.oa.modules.security.entity.SystemModule;
import com.useeinfo.oa.modules.security.entity.SystemResource;
import com.useeinfo.oa.modules.security.vo.TreeVO;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;

/**
 * Author: 居泽平
 */
@Service("systemAuthorityBizWeb")
public class SystemAuthorityBiz extends CrudBiz<SystemAuthorityDao, SystemAuthority> {

    @Autowired
    private SystemResourceBiz systemResourceBiz;
    @Autowired
    private SystemModuleBiz systemModuleBiz;
    @Autowired
    private SystemRoleBiz systemRoleBiz;

    @Transactional
    public void addSystemAuthorityFirst(String authorityName) {
        logger.info("authorityName的值为：" + authorityName);

        QueryParam queryParam = new QueryParam();
        queryParam.getSqlMap().put("authorityName", authorityName);
        List<SystemAuthority> systemAuthorityList = findList(queryParam);
        //若list为空则做新增操作
        if (CollectionUtils.isEmpty(systemAuthorityList)) {
            //执行新增操作
            SystemAuthority systemAuthority = new SystemAuthority(authorityName, authorityName, null, null, true, true);
            addOrUpdate(systemAuthority);
        }
    }

    public Boolean existAuthorityName(SystemAuthority systemAuthority) {
        //若权限名称为空
        logger.info("权限名称为：" + systemAuthority.getAuthorityName());
        if (StringUtils.isBlank(systemAuthority.getAuthorityName())) {
            return true;
        }

        //根据权限名称查询
        QueryParam queryParam = new QueryParam();
        SystemModule systemModule = CommonSugar.getTypedDefault(systemAuthority.getSystemModule(), new SystemModule());
        queryParam.getSqlMap().put("moduleId", systemModule.getId() + "");
        queryParam.getSqlMap().put("authorityName", systemAuthority.getAuthorityName());
        List<SystemAuthority> systemAuthorityList = findList(queryParam);

        if (systemAuthority.getId() == null) {
            //新增操作，判断列表size是否为0
            return CollectionUtils.isNotEmpty(systemAuthorityList);
        } else {
            //修改操作，情况一：判断list长度是否为1，并且与自身相同，那么就是不存在，所以结果取反
            //修改操作，情况二：判断list长度是0
            return !((systemAuthorityList.size() == 1 && systemAuthorityList.get(0).getId().equals(systemAuthority.getId())) || systemAuthorityList.size() == 0);
        }
    }

    public List<SystemAuthority> getAuthoritiesByRoleId(Long roleId) {

        QueryParam queryParam = new QueryParam();
        queryParam.getSqlMap().put("existsRoleId", roleId == null ? "-1" : roleId.toString());

        return findList(queryParam);
    }

    public List<SystemAuthority> getOtherAuthoritiesByRoleId(Long roleId) {

        QueryParam queryParam = new QueryParam();
        queryParam.getSqlMap().put("notExistsRoleId", roleId == null ? "-1" : roleId.toString());

        return findList(queryParam);
    }

    public Map<String, Object> getAuthAndResourceById(Long authId) {
        Map<String, Object> map = new HashMap<>();
        SystemAuthority auth = findModel(authId);
        List<SystemResource> ownResource = systemResourceBiz.getResourceByAuthId(authId);
        List<SystemResource> otherResource = systemResourceBiz.getOtherResourceByAuthId(authId);
        map.put("auth", auth);
        map.put("ownResource", ownResource);
        map.put("otherResource", otherResource);
        return map;
    }

    @Transactional
    public SystemResource addResourcesToAuthorities(Long authId, Long resId) {
        SystemResource systemResource = systemResourceBiz.findModel(resId);
        SystemAuthority systemAuthority = findModel(authId);
        systemAuthority.addResource(systemResource);
        return systemResource;
    }

    @Transactional
    public SystemResource deleteResourcesFromAuthorities(Long authId, Long resId) {
        SystemResource systemResource = systemResourceBiz.findModel(resId);
        SystemAuthority systemAuthority = findModel(authId);
        systemAuthority.removeResource(systemResource);
        return systemResource;
    }

    /**
     * 获取所有权限数据
     *
     * @return
     */
    public ResultDto getRoleAuthoritys(String sysCode, String roleId, Long enterpriseId) {
        AtomicReference<Boolean> flag = new AtomicReference<>(false);
        String mocode = "m_";
        JSONObject data = new JSONObject();
        List<TreeVO> treeVOList = new ArrayList<>();
        QueryParam queryParam = new QueryParam();
        queryParam.getSqlMap().put("enterpriseId", enterpriseId + "");
        List<SystemAuthority> systemAuthorities = this.findList(queryParam);
        List<Long> keys = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(systemAuthorities)) {
            systemAuthorities.forEach(systemAuthority -> {
                SystemModule systemModule = systemAuthority.getSystemModule();
                Long systemModuleId = systemModule != null ? systemModule.getId() : 0L;
                if (systemModule != null && !keys.contains(systemModule.getId())) {
                    treeVOList.add(new TreeVO(systemModule.getModuleName(), "0",
                            mocode + systemModule.getId(), systemModule.getModuleName(), "module"));
                    keys.add(systemModule.getId());
                } else {
                    flag.set(true);
                }
                treeVOList.add(new TreeVO(systemAuthority.getAuthorityDescription(), mocode + systemModuleId,
                        systemAuthority.getId() + "", systemAuthority.getAuthorityName(), "auth"));
            });
        }
        if (flag.get()) {
            treeVOList.add(new TreeVO("其他", "0",
                    mocode + "0", "其他", "module"));
        }

        QueryParam queryParam1 = new QueryParam();
        queryParam1.getSqlMap().put("systemModuleIsNull", "true");
        List<SystemAuthority> systemAuthorityList = this.findList(queryParam1);
        if (CollectionUtils.isNotEmpty(systemAuthorityList)) {
            systemAuthorityList.forEach(systemAuthority -> {
                treeVOList.add(new TreeVO(systemAuthority.getAuthorityDescription(), mocode + "0",
                        systemAuthority.getId() + "", systemAuthority.getAuthorityName(), "auth"));
                    });
        }

        JSONObject menuMap = new JSONObject();
        menuMap.put(sysCode, treeVOList);
        data.put("menuMap", menuMap);

        //选中项
        data.put("roleMenuList", systemRoleBiz.getAuthByRoleId(StringConverters.ToLong(roleId), sysCode));
        return ResultUtil.success(data);
    }

    public List<SystemAuthority> hqlExcute(String hql) {
        return dao.hqlExcute(hql);
    }


    public boolean hasAuthAuthority(String authorityName, Long userId, Long enterpriseId) {
        String authHql = "select obj from SystemAuthority obj left join obj.systemModule as sm where obj.deleteStatus = false and ( sm is null  or" +
                " sm.applicationModuleId in ( select al.id from  ApplicationModule al" +
                " where exists ( select ep from al.enterpriseSet ep where ep.id = " + enterpriseId + ")))" +
                " and exists ( select r from obj.roleSet r where r.id in ( select ure.systemRole.id from UserRoleEnterprise ure where  ure.deleteStatus= false and " +
                " ure.enterprise.id = " + enterpriseId + " and ure.systemUser.id = " + userId + " )) and obj.authorityName = '" + authorityName + "' ";
        List<SystemAuthority> authorityList = dao.hqlExcute(authHql);
        if(CollectionUtils.isNotEmpty(authorityList)){
            return true;
        }
        return false;
    }

}



